Page 1 of 1

Controllo remoto con ip dinamico senza dns

Posted: Sat Dec 01, 2012 10:24 pm
by guitar
Salve a tutti volevo condividere la mia esperienza con il raspberry.
Utilizzandolo con transmission e come nas mediante una connessione con ip dinamico, il controllo remoto diviene possibile solo se si utilizza un servizio esterno di dns dinamico ma non solo. Poichè semplicemente provo antipatia per i servizi di dns dinamico ha cercato un altro metodo per raggiungere il rasp da remoto. La scelta è ricaduta su irc. Inizialmente ho iniziato a scrivere un bot irc in modo che il rasp si collegasse automaticamente a un server irc in un determinato chan e semplicemente chattando potevo inviargli dei comandi e devo dire di aver ottenuto buoni risultati. Chi volesse approfondire la scrittura di un client o un bot o un bouncer irc, questa è un ottima libreria che implementa i comandi client del protocollo irc http://www.ulduzsoft.com/linux/libircclient/
In seguito, un po' per pigrizia, un po' per mancanza di tempo e un po' per non reinventare la ruota o cercato una soluzione alternativa che si basasse sulla mia idea. La scelta è ricaduta su znc http://wiki.znc.in/ZNC ZNC è un bouncer irc che ha molti moduli che hanno diverse funzioni. Uno dei più interessanti è il modulo shell. Con questo modulo è possibile avere una shell remota semplicemente chattando su irc con il vostro rasp. La configurazione di znc è molto semplice basta eseguire uno script che chiede di volta in volta il nome del server del chan del owner (proprietario) e così via. Non scendo nei dettagli un po' per pigrizia e un po' perchè non me li ricordo.
Scusate il tedio.
Ciao

Re: Controllo remoto con ip dinamico senza dns

Posted: Mon Dec 03, 2012 7:14 am
by Dagon84
Beh, sicuramente una idea originale!

Sinceramente lo trovo un pò scomodo, anche perchè io un server IRC non lo apro almeno da 7 anni, però è una buona alternativa alle "Multinazionali del DNS" :D

Grazie per la segnalazione :D

Re: Controllo remoto con ip dinamico senza dns

Posted: Mon Dec 03, 2012 4:41 pm
by NothingAtAll
Io mi ero posto tuo stesso problema per puro divertimento e ho trovato due soluzioni diverse:
1. Pubblico periodicamente il mio IP su una pagina web protetta.
2. Metto il mio IP su un file che condivido in cloud con me stesso.
Per la prima soluzione oggi ho anche prodotto del codice funzionante, se vi interessa ve lo propino. :D

Re: Controllo remoto con ip dinamico senza dns

Posted: Mon Dec 03, 2012 6:01 pm
by hitman80
Oppure puoi usare uno script per inviartelo via email + cron come descritto da un altro utente italiano :

http://www.raspberrypi.org/phpBB3/viewt ... 8&p=210192

http://rpy-italia.org/forum/index.php/topic,153.0.html

Re: Controllo remoto con ip dinamico senza dns

Posted: Mon Dec 03, 2012 7:58 pm
by NothingAtAll
Non male l'idea della mail, solo che se ti arriva la mail che la temperatura è alle stelle e stai fuori casa rosichi non poco :mrgreen: Scherzi a parte mi sembra la soluzione più pulita se non si vuole usare un DNS di terze parti.

Re: Controllo remoto con ip dinamico senza dns

Posted: Tue Jul 23, 2013 7:45 pm
by guitar
Salve a tutti, ho rimuginato un po' sulla soluzione a questo problema e credo che si possa fare una cosetta carina. Ultimamente mi va di fare le cose per bene e prima di scrivere codice all'impazzata, butto giù le idee per avere una definizione migliore del problema cosi ho redatto un primo documento di quello che vorrei realizzare magari con la collaborazione di qualche coder c qui presente.
PrivateDNS

Lo scopo di questo sistema è quello di risolvere un IP pubblico di una rete remota di nostra proprietà che:

1) non dispone di regolare registrazione DNS
2) si appoggia a un provider che rilascia IP pubblico dinamico

La soluzione convenzionale è di appoggiarsi a un servizio di DNS dinamico con tutto ciò che ne consegue.
Molto importante, la soluzione proposta è valida solo e soltanto nel caso in cui non ci sia la necessità che la risoluzione dell' IP debba essere pubblica o meglio a disposizione di tutti.
Il sistema comporta 2 programmi, uno in esecuzione su un server della rete da raggiungere e l'altro in esecuzione sulla macchina richiedente. Entrambi i programmi girano in background.
Il programma installato sul server della rete da raggiungere, si collega a un determinato server e a un canale IRC. Ricevendo un apposito comando passato tramite chat, ritornerà l'IP pubblico della rete a cui appartiene. Questo comando quindi potrà essere inoltrato mediante un qualsiasi client IRC basterà conoscere il server e il canale IRC e una password.
La procedura è automatizzata dal secondo programma installato sulla macchina del richiedente. Questo programma collegandosi allo stesso server e canale IRC a cui è connesso il server, richiederà l' IP pubblico con una certa frequenza. Ottenuto l' IP, il programma provvederà ad aggiornare una riga del file /etc/hosts. Da questo momento disporremo di un dominio remoto privato (è necessario che il file /etc/host.conf contenga la riga “order hosts,bind”).
Questo secondo programma potrà anche essere scritto per windows solo che andrà a modificare il file c:\windows\system32\drivers\etc\hosts.
Un possibile scenario è quello di disporre su un drive USB le due versioni del secondo programma (per linux e windows) e il relativo file di configurazione che conterrà: il nome del server IRC, il nome del canale IRC, la password e il nome del dominio privato.
Che ne pensate?

Re: Controllo remoto con ip dinamico senza dns

Posted: Wed Jul 31, 2013 12:40 pm
by guitar
Ecco qualcosa di concreto. TODO gestire riconnessione in caso di caduta della connessione a internet.

Code: Select all

// PrivateDNS 
// guitar 2013
// Server side program
// Requirement: libircclient, libconfig, curl

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <libconfig.h>
#include "libircclient.h"

const char *irchost;
int ircport;
const char *nick;
const char *chan;
const char *password;

config_t cfg;

int logged=0;
char owner[128];

void loadconf() {

	config_init(&cfg);

	/* Read the file. If there is an error, report it and exit. */
	if(! config_read_file(&cfg, "ircbot.conf"))
	{
		fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
		config_error_line(&cfg), config_error_text(&cfg));
		config_destroy(&cfg);
		return;
	}
	
	if(config_lookup_string(&cfg, "irchost", &irchost)){	
		printf("Irc host name: %s\n", irchost);
	}else{
		fprintf(stderr, "No 'irchost' setting in configuration file.\n");
	}

	if(config_lookup_int(&cfg, "ircport", &ircport)){	
		printf("Irc port: %d\n", ircport);
	}else{
		fprintf(stderr, "No 'ircport' setting in configuration file.\n");
	}

	if(config_lookup_string(&cfg, "chan", &chan)){	
		printf("Irc chan name: %s\n", chan);
	}else{
		fprintf(stderr, "No 'chan' setting in configuration file.\n");
	}
	
	if(config_lookup_string(&cfg, "nick", &nick)){	
		printf("Irc nick name: %s\n", nick);
	}else{
		fprintf(stderr, "No 'nick' setting in configuration file.\n");
	}
	
	if(config_lookup_string(&cfg, "password", &password)){	
		printf("Irc password loaded\n");
	}else{
		fprintf(stderr, "No 'password' setting in configuration file.\n");
	}	
}


void dump_event (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count)
{
	
}

/*
void event_join (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count)
{

}
*/

void event_connect (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count)
{	
	irc_cmd_join (session, chan, 0);
}


void event_privmsg (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count)
{
	char nickbuf[128];
	FILE *pf;
	char data[20];
	
	if ( count != 2 )
		return;
	
	if ( !origin )
		return;
	
	irc_target_get_nick (origin, nickbuf, sizeof(nickbuf));
	
	if (logged && !strcmp(owner, nickbuf)){
			if (!strcmp(params[1], "exit")){
				logged=0;
				irc_cmd_msg(session, owner, "now you are out");
			}
			if (!strcmp(params[1], "ip")){
				pf=popen("curl ifconfig.me/ip","r");
				if(!pf){
					fprintf(stderr, "Could not open pipe for output.\n");
					return;
				}
				fgets(data, 20 , pf);
				irc_cmd_msg(session, owner, data);
				if (pclose(pf) != 0)
					fprintf(stderr," Error: Failed to close command stream \n");
			}	
			if (!strcmp(params[1], "help"))
				irc_cmd_msg(session, owner, "coming soon");
				
			if (!strcmp (params[1], "quit"))
				irc_cmd_quit (session, "bye");
		
	}else{
		if (strstr (params[1], "pass ") == params[1] && strlen(params[1]) > 5) {
			if (!strcmp(password, params[1]+5)){
				logged=1;
				strcpy(owner, nickbuf);
				irc_cmd_msg(session, owner, "now you are logged in, type help");
			}		
		}
	}
}

/*
void event_channel (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count)
{
}
*/


int main (int argc, char **argv)
{
	
	irc_callbacks_t	callbacks;
	irc_session_t * s;

	memset (&callbacks, 0, sizeof(callbacks));

	callbacks.event_connect = event_connect;
	callbacks.event_join = event_join;
	callbacks.event_nick = dump_event;
	callbacks.event_quit = dump_event;
	callbacks.event_part = dump_event;
	callbacks.event_mode = dump_event;
	callbacks.event_topic = dump_event;
	callbacks.event_kick = dump_event;
	callbacks.event_channel = event_channel;
	callbacks.event_privmsg = event_privmsg;
	callbacks.event_notice = dump_event;
	callbacks.event_invite = dump_event;
	callbacks.event_umode = dump_event;
	callbacks.event_ctcp_rep = dump_event;
	callbacks.event_ctcp_action = dump_event;
	callbacks.event_unknown = dump_event;

	loadconf();

	s = irc_create_session (&callbacks);

	if ( !s )
	{
		printf ("Could not create session\n");
		return 1;
	}


	irc_option_set( s, LIBIRC_OPTION_SSL_NO_VERIFY );	
	
	
	// Initiate the IRC server connection
	if ( irc_connect (s, irchost, ircport, 0, nick, 0, 0) )
	{
		printf ("Could not connect: %s\n", irc_strerror (irc_errno(s)));
		return 1;
	}

	// and run into forever loop, generating events
	if ( irc_run (s) )
	{
		printf ("Could not connect or I/O error: %s\n", irc_strerror (irc_errno(s)));
		return 1;
	}
	config_destroy(&cfg);
	return 1;
}

comando per la compilazione

Code: Select all

gcc -Wall `pkg-config --cflags libconfig` libircclient.o ircbot.c -o ircbot `pkg-config --libs libconfig`