En los scripts que escribimos, a menudo, es necesario conocer la IP pública
de nuestra red, o la IP privada y la dirección MAC de una interfaz de red. Con
el comando ifconfig
podemos conocer la información de las interfaces de red:
$ ifconfig
eth0 Link encap:Ethernet direcciónHW 00:11:22:33:44:55
Direc. inet:192.168.0.30 Difus.:192.168.0.255 Másc:255.255.255.0
Dirección inet6: fe80::203:dff:fe3c:f419/64 Alcance:Enlace
ACTIVO DIFUSI–N FUNCIONANDO MULTICAST MTU:1500 Métrica:1
Paquetes RX:1627 errores:0 perdidos:0 overruns:0 frame:0
Paquetes TX:1067 errores:0 perdidos:0 overruns:0 carrier:0
colisiones:0 long.colaTX:1000
Bytes RX:560137 (560.1 KB) TX bytes:235094 (235.0 KB)
Interrupción:19 Dirección base: 0xc800
eth1 Link encap:Ethernet direcciónHW 00:11:22:33:44:66
DIFUSI–N MULTICAST MTU:1500 Métrica:1
Paquetes RX:0 errores:0 perdidos:0 overruns:0 frame:0
Paquetes TX:0 errores:0 perdidos:0 overruns:0 carrier:0 colisiones:0 long.colaTX:1000
Bytes RX:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupción:21 Dirección base: 0x8000 Memoria:ffcfe000-ffcfefff
lo Link encap:Bucle local
Direc. inet:127.0.0.1 Másc:255.0.0.0
Dirección inet6: ::1/128 Alcance:Anfitrión
ACTIVO BUCLE FUNCIONANDO MTU:16436 Métrica:1
Paquetes RX:3299 errores:0 perdidos:0 overruns:0 frame:0
Paquetes TX:3299 errores:0 perdidos:0 overruns:0 carrier:0
colisiones:0 long.colaTX:0
Bytes RX:355696 (355.6 KB) TX bytes:355696 (355.6 KB)
Sin embargo, si queremos utilizar el dato en concreto—la IP privada o la
dirección MAC—, necesitaremos trabajar un poco la salida que muestra
ifconfig
.
IP privada
Para obtener la IP privada (IPv4) de una interfaz concreta, por ejemplo, la eth0:
$ ifconfig eth2 | perl -nle'/((\d+\.){3}\d+)/ && print $1'
192.168.0.30
La expresión regular es suficiente para parsear la salida de ifconfig
y
obtener la dirección IP de la interfaz. Pero esta expresión regular no la
podríamos emplear para descartar una IP privada no válida.
El rango de IP privadas está definido en el RFC 1918 y contempla los rangos:
10.0.0.0 - 10.255.255.255 (10/8 prefix)
172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
Actualizado el 29 de diciembre de 2014
Podemos utilizar el comando ipcalc
para ver los rangos privados:
$ ipcalc 10.0.0.0/8
Address: 10.0.0.0 00001010. 00000000.00000000.00000000
Netmask: 255.0.0.0 = 8 11111111. 00000000.00000000.00000000
Wildcard: 0.255.255.255 00000000. 11111111.11111111.11111111
=>
Network: 10.0.0.0/8 00001010. 00000000.00000000.00000000
HostMin: 10.0.0.1 00001010. 00000000.00000000.00000001
HostMax: 10.255.255.254 00001010. 11111111.11111111.11111110
Broadcast: 10.255.255.255 00001010. 11111111.11111111.11111111
Hosts/Net: 16777214 Class A, Private Internet
$ ipcalc 172.16.0.0/12
Address: 172.16.0.0 10101100.0001 0000.00000000.00000000
Netmask: 255.240.0.0 = 12 11111111.1111 0000.00000000.00000000
Wildcard: 0.15.255.255 00000000.0000 1111.11111111.11111111
=>
Network: 172.16.0.0/12 10101100.0001 0000.00000000.00000000
HostMin: 172.16.0.1 10101100.0001 0000.00000000.00000001
HostMax: 172.31.255.254 10101100.0001 1111.11111111.11111110
Broadcast: 172.31.255.255 10101100.0001 1111.11111111.11111111
Hosts/Net: 1048574 Class B, Private Internet
$ ipcalc 192.168.0.0/16
Address: 192.168.0.0 11000000.10101000. 00000000.00000000
Netmask: 255.255.0.0 = 16 11111111.11111111. 00000000.00000000
Wildcard: 0.0.255.255 00000000.00000000. 11111111.11111111
=>
Network: 192.168.0.0/16 11000000.10101000. 00000000.00000000
HostMin: 192.168.0.1 11000000.10101000. 00000000.00000001
HostMax: 192.168.255.254 11000000.10101000. 11111111.11111110
Broadcast: 192.168.255.255 11000000.10101000. 11111111.11111111
Hosts/Net: 65534 Class C, Private Internet
El siguiente script realiza la comprobación de una IP privada, y devuelve 1 si es válida, o 0 en caso contrario:
#!/bin/bash
IP="$1"
# checks for a valid number: 0..255
function v() {
n=${1:-300}
if [ $n -lt 0 ] || [ $n -gt 255 ]; then
echo 0
else
echo 1
fi
}
# parse IP
OLD_IFS=$IFS
IFS='.'
IP=($IP)
IFS=$OLD_IFS
A=${IP[0]}
B=${IP[1]}
C=${IP[2]}
D=${IP[3]}
# private ips. rfc 1918 https://tools.ietf.org/html/rfc1918#page-4
# 10.0.0.0 to 10.255.255.255
# 172.16.0.0 to 172.31.255.255
# 192.168.0.0 to 192.168.255.255
if [ $A -eq 10 -a $(v $B) -eq 1 -a $(v $C) -eq 1 -a $(v $D) -eq 1 ] ||
[ $A -eq 172 -a $B -ge 16 -a $B -le 31 -a $(v $C) -eq 1 -a $(v $D) -eq 1 ] ||
[ $A -eq 192 -a $B -eq 168 -a $(v $C) -eq 1 -a $(v $D) -eq 1 ]; then
echo 1
else
echo 0
fi
Actualizado el 11 de enero de 2014
Otra forma de obtener la IP privada es mediante el comando hostname
:
$ hostname -I
192.168.0.30
Dirección MAC
Para obtener la dirección MAC:
$ ifconfig eth0 | grep -oE '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'
00:11:22:33:44:55
La dirección MAC está compuesta por 6 bytes, separados por dos puntos (:) o guión (-), por ejemplo, 00:11:22:33:44:55. La primera mitad (00:11:22) es el Identificador Único de Organización (OUI), el fabricante. La segunda mitad (33:44:55) es una extensión que permite identificar de forma única cada tarjeta de red para un fabricante concreto. Hay puntos de acceso que ignorarán OUIs inválidos. Está bien saber esto si vamos a cambiar la dirección MAC de una tarjeta. En este enlace se encuentra el listado de OUIs válidos.
Una dirección MAC válida que tiene el último bit del primer byte a 0, se corresponde con una dirección unicast. Si es 1, indica una dirección de grupo, lo que se suele reservar para tráfico multicast. Las direcciones MAC con un origen multicast son invalidas y se ignoran.
Si generamos la dirección MAC de forma aleatoria, deberíamos poner el primer byte a 0, para asegurarnos:
$ echo $(cat /proc/interrupts | md5sum | sed -r 's/^(.{10}).*$/00\1/; s/([0-9a-f]{2})/\1:/g; s/:$//;')
00:1f:7a:2e:ef:c7
Podemos comprobar si el OUI es válido ejecutando:
$ mac=$(ifconfig eth0 | grep -oE '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
$ oui=${mac:0:8}
$ oui=${oui//:/-}
$ test ! -r oui.txt && wget http://standards.ieee.org/develop/regauth/oui/oui.txt # 2.3 MB
$ grep -i $oui oui.txt && echo "Valid OUI" || echo "Not valid OUI"
IP Pública
Si queremos obtener nuestra IP pública (IPv4), podemos recurrir a servicios como el de DynDNS:
$ curl -s checkip.dyndns.org | grep -Eo "[0-9\.]+"
1.2.3.4
Otros servicios:
- checkip.dyndns.org
- fmbip.com
- icanhazip.com
- ifconfig.me
- ip.appspot.com
- ipecho.net/plain
- ipinfo.io
- ip.u3mx.com
- myip.dnsomatic.com
- myip.opendns.com
- snar.co/ip/
- whatismyip.org
- www.check-my-ip.net
- www.ipchicken.com
Actualización a 11 de enero de 2014
Si no queremos depender de terceros y tenemos acceso a algún servidor web, el siguiente código PHP nos devolverá nuestra IP:
<?php echo $_SERVER['REMOTE_ADDR']; ?>
Si en lugar de estar conectados en una LAN, estamos conectados directamente a Internet, en lugar de recurrir a servicios externos, podemos ejecutar:
$ ifconfig | grep 'inet addr:' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{print $1}'
1.2.3.4
Actualizado el 24 de agosto de 2012
Direcciones .arpa
Las direcciones .arpa se utilizan para la resolución inversa de DNS. Así por ejemplo, la IP 1.2.3.4 se asocia al dominio 4.3.2.1.in-addr.arpa.
Si queremos obtener las IP asociadas a dominios .arpa para utilizarlas, por ejemplo, en un script, podemos usar el siguiente alias:
$ alias arpa2ip='(type farpa2ip >/dev/null 2>&1) || farpa2ip() { echo "$1" | awk '\''BEGIN{FS="."}{print $4"."$3"."$2"."$1;}'\''; }; farpa2ip'
Un ejemplo de uso:
$ arpa2ip 12.108.52.65.in-addr.arpa
65.52.108.12
El proceso inverso, obtener una dirección .arpa a partir de una IP, se puede conseguir mediante el siguiente alias:
$ alias ip2arpa='(type fip2arpa >/dev/null 2>&1) || fip2arpa() { echo "$1" | awk '\''BEGIN{FS="."}{print $4"."$3"."$2"."$1".in-addr.arpa";}'\''; }; fip2arpa'
Un ejemplo de uso:
$ ip2arpa 65.52.108.12
12.108.52.65.in-addr.arpa