0

I'm trying to build an application with my RPi 3B that get some data from connected sensors. Once I got the data, I'd like to send them to a computer that is on an external network via a script in Python and the socket library. Here is my code:

On server side (the external computer):

import socket

ip = (([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] 
or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) 
+ ["no IP found"])[0]
print("IP ordinateur local: {}".format(ip))

port = 9999
print("Port d'entrée des données sur l'ordinateur local: {}".format(port))

address = ("",port)

serveur = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serveur.bind(address)

serveur.listen(5)
print("En attente de nouvelles connexions")

client, infosClient = serveur.accept()

print("Nouvelle connexion client établie")
print("Infos client: IP = {}, port = {}".format(infosClient[0],infosClient[1]))

msg = "Serveur: connexion acceptee"
client.send(msg.encode())

flag = False
try:
    while True:
        if flag == False:
            msgRecu = client.recv(1024)
            print("Message reçu: {}".format(msgRecu.decode()))
            msg = input("Entrez une réponse à envoyer \n")
            client.send(msg.encode())
            print("Réponse envoyée")
            print("En attente de la commande d'arrêt")
            flag = True
except KeyboardInterrupt:
    msg = "Le serveur a enclenché la commande d'arret Ctrl+C"
    client.send(msg.encode())
finally:
    print("Fermeture de la connexion")
    client.close()
    serveur.close()

On client side (the RPi):

import socket

ipLocal = (([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] 
or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) 
+ ["no IP found"])[0]

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

ipServeur = input("Entrez l'adresse IP du serveur \n")
portServeur = input("Entrez le port du serveur \n")

try:
    client.connect((ipServeur,int(portServeur)))
except KeyboardInterrupt:
    del client


print("Connexion établie")

msgRecu = client.recv(1024)
print(msgRecu.decode())

msg = input("Entrez un message à envoyer \n")

client.send(msg.encode())
print("Message envoyé")

answer = client.recv(1024)

print("Réponse serveur: {}".format(answer.decode()))

print("Fermeture de la connexion")
client.close()

Unfortunately when I enter the IP address that the server script gives me via the first command (ip = ...), the client script tells me I'm connected but the server one is still waiting for a connection.

I think it could possibly come from the fact that the ip address I get from the command is a local one, but I don't know how to get the external, especially since the network of the server is well protected. A friend told me to use a VPN but I don't know much things about how it works, any idea ?

Update info from comment:
After further discussion it appears the only solution would be to create a VPN. The difficulty here is that the server network is managed and protected by a a subcontracting company.

So the question is: how to create a Virtual Private Network (VPN) for this conditions?

Ingo
  • 40,606
  • 15
  • 76
  • 189
  • What's the question? How to setup a VPN? – Ingo May 09 '19 at 19:34
  • After further discussion it appears the only solution would be to create a VPN, so yes, that is the question. The difficulty here is that the server network is managed and protected by a a subcontracting company. – Marc Aurèle May 10 '19 at 07:12

2 Answers2

2

The usual way to establish a Virtual Private Network is to connect to a VPN server that is well known with its connection conditions. Often it is known a public ip address on the internet to a router that will do port forwarding to the VPN server. How to setup a VPN with known VPN server you can look at Simple openVPN with static keys.

But the problem with your setup is that the possible VPN server isn't reachable due to a well protected remote network. There is a way to poke a hole in this protection from inside the network. You can setup a reverse tunnel using ssh. But because this is a sort of hacking and most network administrator don't like it, I will not give more information about it here. Talk with your network admin how you can reach the VPN server from outside the protected network.

It should be possible to reach your RasPi with sensors from within the protected network, means the other way around should do. For example you can make a script that tries to connect to your RasPi by VPN maybe every 10 minutes.

Ingo
  • 40,606
  • 15
  • 76
  • 189
1

If setting up your own VPN, as described elsewhere, seems a little daunting then consider using a ready made one. For example, I've used ZeroTier One on the Pi in the past and it's worked well without having to do much other than install it on the clients and create a network for them to join using the web dashboard. From there you can add users; manage clients; assign static IP addresses and so on.

To be clear I'm not affiliated in any way with them but I do feel that they are under used alternative to setting up your own VPN without having to fight through configuring IP addresses or port forwarding.

Roger Jones
  • 1,479
  • 5
  • 14