irmen / Pyro4

Pyro 4.x - Python remote objects
http://pyro4.readthedocs.io/
MIT License
713 stars 83 forks source link

Daemon + SSL : Connection refused #224

Closed morrolinux closed 4 years ago

morrolinux commented 4 years ago

Hi, I'm using 2-way SSL for connecting a client and a server using a Daemon. Everything works fine if I run both client and server on the same host, but if I run the very same client code on a different host (on the same network) I get: cannot connect to ('t480s', 9090): [Errno 111] Connection refused As far as I understood it is sufficient to bind the daemon on a valid network interface other than default for it to be exposed publicly, and a name server should be optional so I'm not using one. Is it a bug or am I doing something wrong?

Here's my server code:

        d = CertValidatingDaemon(host=socket.gethostname(), port=9090)
        test_uri = d.register(self, "JobDispatcher")
        d.requestLoop()

And client code:

        self.job_dispatcher = CertCheckingProxy('PYRO:JobDispatcher@t480s:9090')
        self.job_dispatcher.test()    **<--- HERE it crashes**

Stack trace:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/Pyro4/core.py", line 511, in connect_and_handshake
    sock = socketutil.createSocket(connect=connect_location,
  File "/usr/lib/python3.8/site-packages/Pyro4/socketutil.py", line 307, in createSocket
    sock.connect(connect)
  File "/usr/lib/python3.8/ssl.py", line 1342, in connect
    self._real_connect(addr, False)
  File "/usr/lib/python3.8/ssl.py", line 1329, in _real_connect
    super().connect(addr)
ConnectionRefusedError: [Errno 111] Connection refused

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "./run_render_node.py", line 8, in <module>
    node.run()
  File "/home/morro/olive-distributed-rendering/worker_node.py", line 56, in run
    print(self.job_dispatcher.test())
  File "/usr/lib/python3.8/site-packages/Pyro4/core.py", line 275, in __getattr__
    self._pyroGetMetadata()
  File "/usr/lib/python3.8/site-packages/Pyro4/core.py", line 615, in _pyroGetMetadata
    self.__pyroCreateConnection()
  File "/usr/lib/python3.8/site-packages/Pyro4/core.py", line 596, in __pyroCreateConnection
    connect_and_handshake(conn)
  File "/usr/lib/python3.8/site-packages/Pyro4/core.py", line 549, in connect_and_handshake
    raise ce
Pyro4.errors.CommunicationError: cannot connect to ('t480s', 9090): [Errno 111] Connection refused
morrolinux commented 4 years ago

So.. If anyone else is getting the same issue under the same scenario here's what I found out: It appears to be strictly an SSL issue: I was binding the daemon on host=socket.gethostname() and the certificate I was issuing was generated the same way. However I then noticed that pinging the hosts one another was reporting the full domain name like so: PING x1-yoga.homenet.telecomitalia.it (192.168.1.16) 56(84) bytes of data. And it turns out that part actually matters a lot to SSL registered domain. So instead of using socket.gethostname() like everyone is suggesting, I used socket.gethostbyname_ex(socket.gethostname())[0] to get the full domain name. Generating the SSL certificates and binding on this name works fine within local network