jhead / phantom

Use your own Minecraft server with your Xbox or PS4 and play with friends!
MIT License
613 stars 76 forks source link

Docker bridge networking #136

Open claflico opened 3 years ago

claflico commented 3 years ago

I'm experimenting with a Docker image for phantom. When I run the docker container with the network set to host everything works well. When I click the Friends tab on my phone, it shows the IP address of my phone as the client and I'm able to connect to the remote server. It shows my docker host's IP address as the LAN server under Friends.

10:34PM INF Starting idle connection handler
10:34PM INF Binding proxy server to: 0.0.0.0:52490
10:34PM INF Proxy server listening!
10:34PM INF Listener starting up: 0.0.0.0:19132
10:34PM INF Once your console pings phantom, you should see replies below.
10:34PM INF Starting 1 workers
10:34PM INF Listener starting up: 0.0.0.0:52490
10:36PM INF Opening connection to 184.95.54.204:2000 for new client 192.168.XXX.86:43028!
10:36PM INF Opening connection to 184.95.54.204:2000
10:36PM INF Received LAN ping from client: 192.168.XXX.86:43028
10:36PM INF New connection from client 192.168.XXX.86:43028 -> 0.0.0.0:19132
10:36PM INF Sent LAN pong to client: 192.168.XXX.86:43028
10:36PM INF Received LAN ping from client: 192.168.XXX.86:43028
10:36PM INF Sent LAN pong to client: 192.168.XXX.86:43028
10:36PM INF Received LAN ping from client: 192.168.XXX.86:43028
10:36PM INF Sent LAN pong to client: 192.168.XXX.86:43028
10:36PM INF Received LAN ping from client: 192.168.XXX.86:43028
10:36PM INF Sent LAN pong to client: 192.168.XXX.86:43028
10:36PM INF Opening connection to 184.95.54.204:2000 for new client 192.168.XXX.86:57137!
10:36PM INF Opening connection to 184.95.54.204:2000
10:36PM INF New connection from client 192.168.XXX.86:57137 -> 0.0.0.0:52490

When I change it to use bridge networking and expose 19132 it shows the docker hosts bridge network IP when I click on the Friends tab on my phone. The server never shows up under my Friends tab.

10:48PM INF Starting idle connection handler
10:48PM INF Binding ping server to port 19132
10:48PM INF Binding proxy server to: 0.0.0.0:50373
10:48PM INF Proxy server listening!
10:48PM INF Once your console pings phantom, you should see replies below.
10:48PM INF Starting 1 workers
10:48PM INF Listener starting up: 0.0.0.0:50373
10:48PM INF Listener starting up: 0.0.0.0:19132
10:51PM INF Opening connection to 74.63.195.30:2000 for new client 172.17.0.1:35914!
10:51PM INF Opening connection to 74.63.195.30:2000
10:51PM INF Received LAN ping from client: 172.17.0.1:35914
10:51PM INF New connection from client 172.17.0.1:35914 -> 0.0.0.0:19132
10:51PM INF Sent LAN pong to client: 172.17.0.1:35914
10:51PM INF Received LAN ping from client: 172.17.0.1:35914
10:51PM INF Sent LAN pong to client: 172.17.0.1:35914
10:51PM INF Received LAN ping from client: 172.17.0.1:35914
10:51PM INF Sent LAN pong to client: 172.17.0.1:35914

I don't think that I can use the -bind option and specify my hosts IP address inside the container because it wouldn't be a valid IP address for the application to bind to.

I'm hoping to be able to run multiple containers of phantom connecting to different servers via the bridge network with a random port externally exposed and then use manymine (https://github.com/illiteratealliterator/manymine) to announce those servers to the LAN.

Could an argument such as host_ip be added that if present would be used in pong replies when running inside of Docker?

jhead commented 3 years ago

Hey @claflico! Thanks for the report. I've had similar issues with Docker bridge networks and phantom.

Your second snippet seems to imply that the client's IP isn't being forwarded past the Docker bridge, so it's being replaced with that 172.17.0.1 IP. That IP needs to actually be the same as your first snippet, which means your Docker container needs to be able to reach out to your LAN. Without this, phantom is receiving the ping but sending a response to the bridge instead of the client, which goes nowhere at all.

This is a shot in the dark but have you tried enabling IP forwarding on your host OS? https://docs.docker.com/network/bridge/#enable-forwarding-from-docker-containers-to-the-outside-world

samhardeman commented 3 years ago

I've experienced issues like this and adding --network=host directly after docker run usually fixes the problem. It makes the docker container piggyback on the network of the host. I think that's also explained in the article @jhead sent.

claflico commented 3 years ago

Correct. When I run it as host it works fine. But I want to be able to run multiple instances at once via bridge mode so the kids can connect to different servers and use manymine to handle the lan detection. Can't run multiple as host unless specifying different host IPs for each.

cpuguy83 commented 3 years ago

@claflico Have you tried with macvlan or ipvlan networks? A little extra work in that you have to setup the network, but it puts the containers on the host network subnet. I'm not familiar with the protocol used for proxy here so it may not work on that interface type... but worth a try.

claflico commented 3 years ago

@jhead I finally got a chance to test the change to the iptables config but unfortunately it still didn't work. Even after restarting docker the ping was still seen as coming from 172.17.0.1. instead of my actual client ip.

@cpuguy83 I actually used to use macvlan for my setup and had 3 additional IPs added to my docker host. After I found manymine I was able to do away with the macvlan stuff and just use the default bridge networking.

I'm actually researching/working on a larger minecraft project that I'm hoping will incorporate both manymine and phantom proxy to make it easier for people to connect and play together on private servers from different networks/households.

claflico commented 3 years ago

You can close this if you wish. I wrote a docker image that utilizes Traefik that can act as a proxy to remote Bedrock & Java servers:

https://github.com/cubeworx/cbwxproxy https://hub.docker.com/r/cubeworx/cbwxproxy