Conéctate para seguir esto  
chujalt

Saber nuestra IP publica. Servicio tipo no-ip o DynDNS

22 posts en este tema

Saludos amigos.

 

Si tenemos un servidor montado en casa y nuestro proveedor de internet no nos facilita una IP fija tendremos la necesidad de saber en todo momento nuestra IP pública. Vamos a montar un servicio tipo no-ip o DynDNS.

 

El servicio consta de dos partes, una en nuestro ordenador y por otra parte necesitaremos un servidor de internet, por ejemplo, si no tenemos un servicio de hosting, https://www.hostinger.es/ , nos ofrece de forma gratuita todo lo que necesitamos, 2 GB de almacenamiento, php y bases de datos MySQL. 

 

 

 

EN NUESTRO ORDENADOR

 

Tengo que aclarar que lo que explico a continuación lo he hecho bajo un sistema linux.

 

En  primer lugar crearemos un directorio en el servidor de nuestro pc, yo lo he llamado curl, la ruta sería /var/www/html/curl.

 

Abrimos nuestro editor de texto favorito y escribimos

 

#!/bin/bash
pepe=$(dig +short myip.opendns.com @resolver1.opendns.com)
curl -d "value1=pepico&value2=$pepe" http://midominio.com/curl/index.php

 

Lo guardamos con el nombre 1.sh, por ejemplo, y le damos permisos de ejecución. En la última linea cambiar midominio.com por el de nuestro servidor de hosting, también, donde vemos value1=pepico. cambiamos el nombre por el que queramos.

 

Este script lo que hace averiguar nuestra ip pública y enviarla, junto a un nombre de usuario a nuestra página index.php del servidor de hosting mediante el método post.

 

Ahora vamos a editar crontab para que nuestro script se ejecute cada dos horas. Abrimos un terminal y escribimos 

 

sudo gedit /etc/crontab

 

y en crontab añadimos esta línea

 

0 */2	* * *	root	/var/www/html/curl/1.sh

 

guardamos y cerramos. Como hemos dicho, ésto hará que nuestro script se ejecute cada dos horas.

 

Ya hemos terminado en nuestro PC, ahora iremos a nuestro servidor de hosting.

 

 

 

EN NUESTRO SERVIDOR DE HOSTING 

 

Deberemos crear una base de datos MySQL con nombre curl, con una tabla llamada datos y 4 columnas, id (int, primary key, auto_increment), nombre (varchar 50), ip (varchar 50) y fecha (timestamp, CURRENT_TIMESTAMP).

 

Ahora vamos a crear la página index que recogerá los datos que le hemos enviado antes por el script bash y los introducirá en nuestra base de datos. Paso previo es crear también una página conex.

 

conex.php 

<?php
// hostname o ip del servidor de Base Datos
$bd_host='localhost';
 
// nombre de usuario 
$bd_usuario='usuario';
 
// la contraseña para la BBDD  
$bd_password='contraseña';
 
// nombre del BBDD
$bd_base='curl';
$conexion = new mysqli($bd_host, $bd_usuario, $bd_password, $bd_base);
 
if ($conexion->connect_errno) 
{
    echo "No se pudo conectar a la Base Datos: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
?>

 

index.php 

<?php

include("conex.php");
if($_POST)
      {
         $queryInsert = "INSERT INTO datos (nombre, ip) VALUES ('".$_POST['value1']."', '".$_POST['value2']."');";
 
         $resultInsert = mysqli_query($conexion, $queryInsert); 
 
         if($resultInsert)
         {
            echo "<strong>Se ingresaron los registros con exito</strong>. <br>";
         }
         else
         {
            echo "No se ingresaron los registros. <br>";
         }
 
      }
?>

 

Con esto ya tenemos nuestra última ip metida en la base de datos.

 

Ahora vamos a crear dos sencillas páginas para saber cual es nuestra actual ip pública de nuestro PC, buscar.php y encontrado.php.

 

buscar.php 

<html>
<head>
<title>Entrada de enlaces</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>

<body>
<form action="encontrado.php" method="post">
  Nombre:<br>
  <input type="text" name="nombre"><br><br>
  <input type="submit" value="Submit">
</form>
</body>
</html>

 

Nos mostrará un sencillo formulario donde debemos poner nuestro nombre de usuario que está en el script bash.

 

encontrado.php 

<html>
<head>
<title>Entrada de enlaces</title>
<meta charset="UTF-8">
</head>
<body>
<?php
include("conex.php");
$consulta = "SELECT nombre, ip, DATE_FORMAT(fecha, 'Con fecha: %d/%m/%y y hora: %H:%i:%s') AS fecha FROM datos WHERE nombre = '" . $_POST["nombre"] . "' ORDER BY id  DESC LIMIT 1";
$resultado = $conexion -> query($consulta);
echo "<span style='color: blue;'>Extracción de último dato ...</span> <br><br>";
while($fila = $resultado -> fetch_array())
{
echo "Usuario: " . $fila["nombre"] . "<br>";
echo "Última IP asignada: " . $fila["ip"] . "<br>";
echo "" . $fila["fecha"] . "<br><hr>";
}
mysqli_free_result($resultado);
mysqli_close($conexion);
?>
</body>
</html>

 

Nos mostrará la última ip pública que tenemos asignada y a que fecha y hora se captó.

 

Extracción de último dato ... 

Usuario: pepico
Última IP asignada: 11.111.11.111
Con fecha: 29/04/17 y hora: 18:00:02

 

Todo esto está bien, pero queremos algo mas, no tener que ir a un formulario para saber nuestra ip, lo que queremos es poner en el navegador una dirección y que nos redireccione a nuestro servidor local, una dirección tipo "midominio.com/pepico". Recordad que pepico era nuestro usuario con el que se guardaban las ip de nuestro servidor local.

 

Bien, como al poner esa dirección en el navegador, el directorio pepico no existe, el servidor nos enviará un error 404, página no encontrada. Vamos a crear una página de error 404 tuneada por nosotros.

 

Antes de nada vamos a tener que tocar el archivo .htaccess para que cuando se de el error 404 nos muestre nuestra página 404. Abrimos el archivo .htaccess y añadimos la linea
 

ErrorDocument 404 /404.php

 

Con esto le decimos que cuando se produzca el error 404 nos muestre la página 404.php.

 

Ahora vamos a crear la página 404.php, que a continuación diré lo que hace.

 

404.php 

<html>
<head>
<title>Entrada de enlaces</title>
<meta charset="UTF-8">
<script language="JavaScript">
function enviar()
{
document.form.submit();
}
</script>
</head>
<body onload="enviar()">
<?php
$url =  "{$_SERVER['REQUEST_URI']}";
$resultado = str_replace("/", "", $url);
?>
<form method="POST" action="curl/redireccionar.php" name="form">
<p><input type="text" value="<?php echo $resultado; ?>" name="nombre"></p>
<p><input type="submit" value="Enviar" name="B1"></p>
</form>
</body>
</html>

 

Esta página lo que hace es eliminar de la dirección web todo lo que vaya antes de la barra "/", en nuestro caso quedaría pepico y lo envía directamente a otra página que luego vamos a crear, redireccionar.php, la cual estará dentro del directorio curl.

 

 redireccionar.php

<html>
<head>
<title>Entrada de enlaces</title>
<meta charset="ISO-8859-1" />
</head>
<body>
<?php
include("conex.php");
$consulta = "SELECT nombre, ip, DATE_FORMAT(fecha, 'Con fecha: %d/%m/%y y hora: %H:%i:%s') AS fecha FROM datos WHERE nombre = '" . $_POST["nombre"] . "' ORDER BY id  DESC LIMIT 1";
$resultado = $conexion -> query($consulta);
 
if ($fila = $resultado -> fetch_array())
{ 
echo "<script language=\"javascript\">window.location.href=\"http://" . $fila["ip"] . "\";</script>";
}
else {
echo "NO encontrado";
}
mysqli_free_result($resultado);
mysqli_close($conexion);


?>
</body>
</html>

 

Esta página lo que hace es buscar en la base de datos la última ip registrada del usuario que queremos, en este caso pepico, y nos redirecciona directamente a esa ip. Si ese usuario no existe o nos equivocamos al escribir la dirección, la página actuará como una página 404 y nos mostrará un mensaje de "no encontrada".

 

Todo el proceso, desde que pones la dirección en el navegador hasta que te redirecciona a la ip de tu servidor local es limpio y automático.


Bueno, espero que le sirva a alguien de ayuda.

 

Saludos.

Compartir este post


Enlace al post
Compartir en otros sitios

Me ha gustao esta guia, la acabo de ver, la voy a poner en practica mañana, que este carrozon esta ya en la cama.

 

Lo que he entendido es que el servicio de hosting gratuito de hostinger, nos hara las veces de un servicio de pago como es DynDNS

 

Muy buena idea, es la magia que tiene la consola de linux, que facilita la vida con unas cuantas lineas de codigo.

 

:ok:

Compartir este post


Enlace al post
Compartir en otros sitios

Hola chujalt, hay algo que no va, en la base de datos del servidor remoto el valor que se almacena en el campo de la IP, es:

 

;; connection timed out; no servers could be reach

 

no se que puedo hacer mal.

Tanto en el servidor remoto como en mi servidor apache local, en debian 8, he creado la carpeta curl

-en el local: /var/www/html/curl

y he entendido que va el archivo ejecutable 1.sh, y todos los demas en el hosting remoto, tambien dentro de la carpeta ../curl

 

cuando ejecuto en mi debian local ./1.sh la salida es esta:

<strong>Se ingresaron los registros con exito</strong>. <br>root@pc1:/var/www/html/curl#

 

Estoy cayendo en la cuenta que quizás el problema es que no tengo habierto el puerto 80 en el router, voy a verlo...

Compartir este post


Enlace al post
Compartir en otros sitios

En el pequeño script bash 1.sh, supongo que esta línea:

pepe=$(dig +short myip.opendns.com @resolver1.opendns.com)

supongo que sirve para almacenar en la variable 'pepe' nuestra IP local externa con la que salimos a internet.

El comando dig, según he buscado en google, "es una herramienta para realizar consultas a los servidores DNS para solicitar información sobre direcciones de host, intercambiadores de correo, servidores de nombres e información relacionada".

 

Su sintaxis sería

dig @servidor-dns ejemplo.com tipo-de-registro

La opción +short he leido que sirve para obtener una salida simplificada del comando dig

Yo no se porqué a mi este comando "dig +short myip.opendns.com @resolver1.opendns.com" no me funciona en la consola de mi debian 8, se supone que haciendo una llamada al host externo "myip.opendns.com" a través del servidor DNS  "resolver1.opendns.com" debería devolverme mi IP externa, pero a mi lo que me devuelve es:

 

;; connection timed out; no servers could be reach

 

Por otro lado, accediendo desde nuestra maquina local al host remoto (nuestra web de hostinger), ya va impresa nuestra IP en las cabeceras http, por lo cual no sería necesario enviar explicitamente nuestra IP al host remoto, bastaria con obtener la ip de las cabeceras con la superglobal php $_SERVER['REMOTE_ADDR']

 

 

 

Editado por pprico

Compartir este post


Enlace al post
Compartir en otros sitios

Acabo de encontrar este artículo que me ha parecido muy completo sobre como "obtener la IP real de una visita web en PHP"

 

Esta función, que si se quiere se puede simplificar, nos daría salida nuestra IP en texto simple

 

<?php

function getRealIP()
{
 
   if( $_SERVER['HTTP_X_FORWARDED_FOR'] != '' )
   {
      $client_ip = 
         ( !empty($_SERVER['REMOTE_ADDR']) ) ? 
            $_SERVER['REMOTE_ADDR'] 
            : 
            ( ( !empty($_ENV['REMOTE_ADDR']) ) ? 
               $_ENV['REMOTE_ADDR'] 
               : 
               "unknown" );
 
      // los proxys van añadiendo al final de esta cabecera
      // las direcciones ip que van "ocultando". Para localizar la ip real
      // del usuario se comienza a mirar por el principio hasta encontrar 
      // una dirección ip que no sea del rango privado. En caso de no 
      // encontrarse ninguna se toma como valor el REMOTE_ADDR
 
      $entries = preg_split('/[, ]/', $_SERVER['HTTP_X_FORWARDED_FOR']);
 
      reset($entries);
      while (list(, $entry) = each($entries)) 
      {
         $entry = trim($entry);
         if ( preg_match("/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/", $entry, $ip_list) )
         {
            // http://www.faqs.org/rfcs/rfc1918.html
            $private_ip = array(
                  '/^0\./', 
                  '/^127\.0\.0\.1/', 
                  '/^192\.168\..*/', 
                  '/^172\.((1[6-9])|(2[0-9])|(3[0-1]))\..*/', 
                  '/^10\..*/');
 
            $found_ip = preg_replace($private_ip, $client_ip, $ip_list[1]);
 
            if ($client_ip != $found_ip)
            {
               $client_ip = $found_ip;
               break;
            }
         }
      }
   }
   else
   {
      $client_ip = 
         ( !empty($_SERVER['REMOTE_ADDR']) ) ? 
            $_SERVER['REMOTE_ADDR'] 
            : 
            ( ( !empty($_ENV['REMOTE_ADDR']) ) ? 
               $_ENV['REMOTE_ADDR'] 
               : 
               "unknown" );
   }
 
   return $client_ip;
 
}

?>

 

Añadiendo esta funcion al archivo buscar.php ya no sería necesario enviar la IP a través del scrip 1.sh

éste se podria limitar a hacer un simple acceso a la web del hosting remoto en nuestra tarea cron

Compartir este post


Enlace al post
Compartir en otros sitios

Es raro...

 

A ver si no tienes instalado dig, aunque a mi, yo uso Ubuntu, me venía por defecto.

 

sudo apt-get install dnsutils

A ver si así te funciona.

 

Si no., prueba con curl. Abre un terminal y teclea

 

curl ifconfig.me/ip

 

A ver si te sale tu ip. A mi los dos métodos me funcionan, lo que pasa es que me decidí por dig porque es mas rápido, unos segundos.

 

Saludos

Compartir este post


Enlace al post
Compartir en otros sitios
hace 53 minutos, chujalt dijo:

Es raro...

 

A ver si no tienes instalado dig, aunque a mi, yo uso Ubuntu, me venía por defecto.

 


sudo apt-get install dnsutils

A ver si así te funciona.

 

Si no., prueba con curl. Abre un terminal y teclea

 


curl ifconfig.me/ip

 

A ver si te sale tu ip. A mi los dos métodos me funcionan, lo que pasa es que me decidí por dig porque es mas rápido, unos segundos.

 

Saludos

 

Si tengo instalado dnsutils

 

curl ifconfig.me lo mismo que curl ifconfig.me/ip

si me da la IP

 

el comando dig no me funciona con ningun host ni con ningun DNS

 

por ejemplo esto deberia funcionar: dig @8.8.8.8 google.com

y tampoco

 

Compartir este post


Enlace al post
Compartir en otros sitios

Si, así si funciona, pero a veces tarda demasiado y sale el mensaje

 

curl: (7) Failed to connect to ifconfig.me port 80: Expiró el tiempo de conexión

 

Las iptables las he desactivado para probar,  que no debería.

Compartir este post


Enlace al post
Compartir en otros sitios

Saludos....

 

Me has dado una idea.

 

Elegí el comando dig porque Curl a veces da fallos, se ve que la página donde apunta a veces está saturada y tarda mucho, hasta cortar la conexión como te ocurre a ti.

 

Vamos a crear una página en el hosting llamada ip.php con el siguiente código, la cual irá dentro del directorio curl.

 

ip.php 

<?php 
echo "{$_SERVER['REMOTE_ADDR']}";
?>

 

Ahora, en el script 1.sh cambiaremos la linea

pepe=$(dig +short myip.opendns.com @resolver1.opendns.com)

por

pepe=$(curl tudominio.com/curl/ip.php)

 

Claro, donde pone "tudominio.com" lo cambias por la dirección de tu hosting.

 

Ahora ya no se dependerá de terceros y me imagino que irá mas rápido y sin fallos.

 

A mi me ha funcionado.

 

Ya me dirás.

 

Saludos

Compartir este post


Enlace al post
Compartir en otros sitios
hace 4 horas, chujalt dijo:

Saludos....

 

Me has dado una idea.

 

Elegí el comando dig porque Curl a veces da fallos, se ve que la página donde apunta a veces está saturada y tarda mucho, hasta cortar la conexión como te ocurre a ti.

 

Vamos a crear una página en el hosting llamada ip.php con el siguiente código, la cual irá dentro del directorio curl.

 

ip.php 


<?php 
echo "{$_SERVER['REMOTE_ADDR']}";
?>

 

Ahora, en el script 1.sh cambiaremos la linea


pepe=$(dig +short myip.opendns.com @resolver1.opendns.com)

por


pepe=$(curl tudominio.com/curl/ip.php)

 

Claro, donde pone "tudominio.com" lo cambias por la dirección de tu hosting.

 

Ahora ya no se dependerá de terceros y me imagino que irá mas rápido y sin fallos.

 

A mi me ha funcionado.

 

Ya me dirás.

 

Saludos

 

 

Si, tambien me funciona.

Pero se me ocurre que se puede simplificar más. El archivo ip.php proporciona la nuestra ip publica, dato que recoge el scrip 1.sh, y luego se vuelve a enviar otra vez al hosting,

 

Hace un viaje de ida y vuelta que se podría ahorrar tomando ese valor directamente en el hosting a traves de la variable global $_SERVER['REMOTE_ADDR']. No se si me explico.

 

Lo pruebo y luego comento.

Compartir este post


Enlace al post
Compartir en otros sitios

Tambien me funciona de la siguente manera:

 

El el script de la máquina local 1.sh lo dejo así:

 

#!/bin/bash
curl -d "value1=pepico" http://midominio.com/curl/index.php

El 'midominio.com' lo sustituyo por el verdadero dominio de mi hosting de pruebas.

Y en el archivo index.php del hosting, cambio la línea que se corresponde a la queri de inserción:

 

$queryInsert = "INSERT INTO datos (nombre, ip) VALUES ('".$_POST['value1']."', '".$_SERVER['REMOTE_ADDR']."');";

Sustituyendo la llamada al metodo post, por la variable global correspondiente

 

Y tambien funciona, tambén me registra mi IP en la base de datos, es el objetivo de este ejercicio.

 

Compartir este post


Enlace al post
Compartir en otros sitios

Se me ocurren también un par de mejoras, una para no aumentar demasiado el tamaño de la base de datos, insertando un nuevo registro cada dos horas, sería poner antes de realizar la query de inserción, poner un condicional if ...else que verifique si la ip ha cambiado, y si es así ejecutar la query, y si no, no hacer nada.

 

El condicional if se añadiría al archivo index.php quedando asi:

 

<?php

include("conex.php");

if ($_POST)
	{
		$querySelect = "SELECT ip FROM datos ORDER BY fecha DESC LIMIT 1";
		$resultSelect = mysqli_query($conexion, $querySelect);
		if ($resultSelect != $_SERVER['REMOTE_ADDR'])
		{
			$queryInsert = "INSERT INTO datos (nombre, ip) VALUES ('".$_POST['value1']."', '".$_SERVER['REMOTE_ADDR']."');";
			$resultInsert = mysqli_query($conexion, $queryInsert);
			if($resultInsert)
			{
				echo "<strong>Se ingresaron los registros con exito</strong>. <br>";
			}
			else
			{
				echo "No se ingresaron los registros. <br>";
			}
		}
		else
		{
			echo "No ha cambiado la IP. <br>";
		}
	}

 

Y lo segundo es que si curl a veces de fallos, usar en la tarea cron un comando php, como se indica en este artículo:

http://www.elcodigofuente.com/ejecutar-php-cada-x-tiempo-cron-job-837/

 

El archivo 1.sh quedaría así:

wget -N -q http://midominio.com/curl/index.php?value1=pepico

 

O tambien se ejecuta directamente el comando en la tarea cron, sin llamar a ningun script bash

 

0 */2	* * *	wget -N -q http://midominio.com/curl/index.php?value1=pepico

 

 

Editado por pprico

Compartir este post


Enlace al post
Compartir en otros sitios

Si, es una buena solución. Busca el último dato y si el campo ip coincide con la ip no hace nada y si no coincide hace el insert.

 

Si va a ser un único usuario quedaría como pones, si van a ser varios en el select falta el 

WHERE nombre = '" . $_POST["value1"] . "'

 

Saludos

Compartir este post


Enlace al post
Compartir en otros sitios

Yo había pensado en usarlo para mi solo, no se todavía para que, pero con un solo usuario, con lo cual no es necesario pasar por URL la variable 'valor1', e incluso se puede prescindir de la columna 'nombre' de la tabla.

 

Si se amplía para varios usuarios hay que afinar más el condicional del if

y por supuesto falta completar la consulta con un WHERE, para incluir el nombre tal como indicas

 

Saludos

 

Compartir este post


Enlace al post
Compartir en otros sitios

He modificado el código personalizandolo a mi gusto, y me funciona de las dos maneras, para un solo usuario o para varios.

 

El reto para mi sería buscar la forma de configurar un dominio de esos gratis, como los .tk, con IP dinámica.

 

Esta aplicación lo que hace es redirigirte a tu IP, al final se ve algo así en el navegador: http://214.258.124.182/

 

 

 

Compartir este post


Enlace al post
Compartir en otros sitios

Saludos.

 

El código del primer post es totalmente funcional.

 

Se puede simplificar el script bash poniendo tan solo

 

curl -d "value1=pepico" http://midominio.com/curl/index.php

 y en la página index.php cambiar esta linea

 

$queryInsert = "INSERT INTO datos (nombre, ip) VALUES ('".$_POST['value1']."', '".$_POST['value2']."');";

 por esta

 

$queryInsert = "INSERT INTO datos (nombre, ip) VALUES ('".$_POST['value1']."', '".$_SERVER['REMOTE_ADDR']."');";

 Otra cosa es que sólo vaya a haber un usuario, donde podrías quitar en la linea de bash "value1=pepico"  y en el insert de la index.php eliminar el del usuario. Luego en el select tan solo tendrías que recuperar el último registro.

 

Saludos.

Compartir este post


Enlace al post
Compartir en otros sitios

Si claro que el post inicial es funcional, a mi es que me gusta sacarle las tripas a todo y mover roma con santiago

 

lo que a mi no me funciono no fue el codigo, sino uno de los comandos linux que no iba bien en mi distro debian, algun fichero de configuracion, pero lo solvente usando otro comando equivalente.

Compartir este post


Enlace al post
Compartir en otros sitios

Registra una cuenta o conéctate para comentar

Debes ser un miembro de la comunidad para dejar un comentario

Crear una cuenta

Regístrate en nuestra comunidad. ¡Es fácil!

Registrar una cuenta nueva

Iniciar Sesión

¿Ya tienes cuenta? Conéctate aquí.

Iniciar Sesión
Conéctate para seguir esto