pythonubuntutcpvmwaredd-wrt

nc from host -> VM works (port 9050), but VM (running server written in Python) resets connection [TCP RST] from host -> VM on same port (9050)


Background Info

I'm developing a network-enabled embedded device that is intended to communicate with a server. Because this server will be running linux (but I require Windows tools for development), I'm running a VM with Ubuntu Server 14.04 for dev purposes.

The embedded aspect isn't important for this question, as I'm stripping back to the simplest test setup (just have host connect to server on VM to see a TCP connection get established) for troubleshooting.

Network Setup

Sanity Checks Performed

Problem Analysis

Using wireshark, I'm able to see TCP connections working succesfully when performing the nc sanity test (host <-> VM).

When I run the server (written in python, using asyncio) on the VM, and try to connect via nc from the host, the server doesn't see any connection come in (but we know that connecting from nc to the server works, as that was tested inside the VM successfully).

From wireshark I see the host sending a SYN to the VM, after which the VM responds with [RST, ACK]. The host retries transmission twice before giving up.

Questions


Update: Tried nc 192.168.5.118 9050 within the VM and observed the same refused connection behaviour as if I had tried from host. Based on what Adam has said, it looks like we're getting closer. Will try Adam's suggestion as well and post an update.


Solution

  • The RST packet is being sent by the OS to indicate that the port is closed—no process is bound to it and listening. As a result, the client trying to connect will very quickly fail with ECONNREFUSED (connection refused). This is perfectly normal behavior.

    How exactly are you binding to the port in your Python server process? Are you binding to the correct network interface? If you accidentally bound to only the loopback device (localhost or 127.0.0.1), then you'll see exactly what you're describing: local connections from the machine to itself will succeed just fine, but connections from external hosts will fail.

    In Python, you typically use either '' or '0.0.0.0' as the address portion to indicate that you want to bind to all network interfaces; this is equivalent to the C constant INADDR_ANY:

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', port))